<template>
  <div class="chat-container">
    <dynamic-scroller ref="chatAreaContent"
                      :items="messageList"
                      :min-item-size="54"
                      class="chat-area"
                      @scroll="scrollChange">
      <template #default="{ item, active, index }">
        <dynamic-scroller-item :item="item"
                               :active="active"
                               :size-dependencies="[item.content]"
                               :data-index="index"
                               :data-active="active"
                               class="message-item">
          <div :class="{ 'message-right': item.fromUserId === '2' }">
            <div class="message-item-direction">
              <div class="message-item__user">
                <div class="message-item__user__avatar">
                  <!-- <img :src="item.fromUserAvatar" alt="" /> -->
                </div>
                <span class="message-item__user__name">{{ item.name }}</span>
              </div>
              <div class="message-item__content" :class="[item.fromUserId === '1' ? 'content-left' : 'content-right']">
                <!-- 1.普通文本  -->
                <pre v-if="item.type === 'text'">{{ item.content }}</pre>
              </div>
            </div>
          </div>
        </dynamic-scroller-item>
      </template>
    </dynamic-scroller>

    <div class="chat-handle">
      <div class="more-message" :style="{ display: !moreMessage ? 'none' : 'block' }" @click="touchingTheBottom">
        <span>有新消息</span>
      </div>

      <div class="control-board">
        <el-popover placement="top" trigger="click">
          <picker :data="emojiIndex"
                  set="twitter"
                  :show-search="false"
                  :show-preview="false"
                  :show-categories="false"
                  :i18n="I18N"
                  :per-line="12"
                  :emoji-size="25"
                  @select="addEmoji"></picker>
          <template #reference>
            <el-icon>
              <search></search>
            </el-icon>
          </template>
        </el-popover>
      </div>

      <div class="chat-send">
        <el-input id="chat-input"
                  ref="inputContentRef"
                  v-model="inputContent"
                  type="textarea"
                  placeholder="请输入内容"
                  @keydown.enter.prevent="onSendMessage"
                  @blur="(e:any) => cursorIndex = e.srcElement.selectionStart">
        </el-input>

        <div class="chat-input__button">
          <el-button size="small"
                     @click="sendMessage">发送
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { nextTick, onMounted, ref } from "vue";
import { DynamicScroller, DynamicScrollerItem } from "vue-virtual-scroller";
import data from "emoji-mart-vue-fast/data/all.json";
import "emoji-mart-vue-fast/css/emoji-mart.css";
// @ts-expect-error whatever
import { EmojiIndex, Picker } from "emoji-mart-vue-fast/src";
import { Search } from "@element-plus/icons-vue";

// @ts-expect-error whatever
const chatAreaContent = ref<InstanceType<typeof DynamicScroller> | null>(null);

const isScrollBottom = ref(false); // 滚动条是否触底

// 监听滚动事件
function scrollChange(e: any) {
  const ele = e.target;
  //  滚动条是否触底
  isScrollBottom.value = ele.scrollTop === ele.scrollHeight - ele.offsetHeight;
}

const messageList = ref<any>([
  { id: "1", name: "张三", fromUserId: "1", type: "text", content: "发送一条消息" },
  { id: "2", name: "用户二", fromUserId: "1", type: "text", content: "发送一条消息发送一条消息" },
  { id: "3", name: "用户三", fromUserId: "1", type: "text", content: "发送一条消" },
  { id: "4", name: "用户四", fromUserId: "1", type: "text", content: "发送一条消息" },
  { id: "5", name: "用户四", fromUserId: "1", type: "text", content: "发送一条消息" },
  { id: "6", name: "用户四", fromUserId: "2", type: "text", content: "发送一条消息" }
]);

const moreMessage = ref<boolean>(false);

async function touchingTheBottom() {
  moreMessage.value = false;
  await chatAreaContent.value!.scrollToBottom();
}

// function setMock() {
//   setInterval(async () => {
//     messageList.value.push({ id: Date.now(), name: "用户四", fromUserId: "1", type: "text", content: "发送一条消息" });
//
//     if (isScrollBottom.value) {
//       await touchingTheBottom();
//     } else {
//       //   新消息按钮出现
//       moreMessage.value = true;
//     }
//     await nextTick();
//     isScrollBottom.value = chatAreaContent.value?.scrollTop === chatAreaContent.value!.scrollHeight - chatAreaContent.value!.offsetHeight;
//   }, 1000);
// }

const inputContent = ref<string>("");
const cursorIndex = ref<number>(0);
const inputContentRef = ref<HTMLElement | null>(null);

function breakMessageLine() {
  inputContentRef.value?.focus();

  const inputDom = document.getElementById("chat-input");

  const { selectionStart, selectionEnd } = inputDom;

  const contents = inputContent.value.split("");
  // 如果用户选中了内容，选中内容变为换行；如果用户直接光标放在哪里那里就换行
  contents.splice(Math.min(selectionStart, selectionEnd), Math.abs(selectionStart - selectionEnd), "\n");

  const nextSelection = selectionStart + 1;
  inputDom?.setSelectionRange(nextSelection, nextSelection);

  cursorIndex.value = nextSelection;
  inputContent.value = contents.join("");
}

async function sendMessage() {
  if (inputContent.value === "") {
    return;
  }

  // this.$emit('onSendMessage', inputContent.value)
  messageList.value.push({ id: Date.now(), name: "用户四", fromUserId: "2", type: "text", content: inputContent.value });
  await nextTick();
  await touchingTheBottom();

  inputContent.value = "";
}

function onSendMessage(event: any) {
  // 判断按键有没有ctrl
  if (event.ctrlKey) {
    //  按了ctrl + enter 换行
    breakMessageLine();
    return;
  }

  sendMessage();
}

const I18N = {
  categories: {
    recent: "经常使用",
    smileys: "表情与情感",
    people: "人物与身体",
    nature: "动物与自然",
    foods: "食物与饮料",
    activity: "活动",
    places: "旅行与地理",
    objects: "物品",
    symbols: "符号标志",
    flags: "旗帜",
    custom: "Custom"
  }
};
const include = ["smileys"];
const exclude = ["recent", "people", "nature", "foods", "activity", "places", "objects"];
const emojiIndex = new EmojiIndex(data, {
  include,
  exclude
});

function addEmoji(emoticon: any) {
  inputContent.value = inputContent.value.slice(0, cursorIndex.value) + emoticon.native + inputContent.value.slice(cursorIndex.value);
}


onMounted(() => {
  //   1.根据老师id去请求消息列表
  //   2.滚动条到底部
  touchingTheBottom();

  // setMock();
});
</script>

<style lang="scss">
.el-popover {
  width: auto !important;
}
</style>

<style scoped lang="scss">
.chat-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
}

.chat-area {
  flex: 1;
  padding: 0 20px;

  &::-webkit-scrollbar {
    width: 10px;
  }

  &::-webkit-scrollbar-thumb {
    background-color: #9a9a9a;
  }

  &::-webkit-scrollbar-track-piece {
    background-color: #e4e4e4;
  }
}

.message-item {
  &__user {
    display: flex;
    align-items: center;

    &__avatar {
      width: 60px;
      height: 60px;
      background-color: #333333;
      border-radius: 50%;
    }

    &__name {
      margin-left: 10px;
      color: #333333;
    }
  }

  &__content {
    // 消息超过多少换行
    width: fit-content;
    max-width: 240px;
    margin-top: 10px;
    background-color: #666666;
    border-radius: 4px;

    > pre {
      padding: 0 10px;
      font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
      font-size: 14px;
      color: #ffffff;
      word-wrap: break-word;
      white-space: pre-wrap;
    }
  }

  & + .message-item {
    margin-top: 20px;
  }
}

.message-item-direction {
  display: flex;
  flex-direction: column;
  padding-top: 20px;
}

.message-right {
  flex-direction: row-reverse;
  margin-left: 0;

  .message-item-direction {
    flex-direction: column;
    align-items: flex-end;
  }

  .message-item__user {
    flex-direction: row-reverse;

    &__name {
      margin-right: 10px;
    }
  }
}


.content-right {
  color: #00ffff;
  background-color: #3e3e3e;
}

.chat-handle {
  position: relative;
  height: 80px;
}

.more-message {
  position: absolute;
  bottom: 100px;
  left: 50%;
  padding: 6px 10px;
  color: #ffffff;
  cursor: pointer;
  background-color: rgba(0, 0, 0, .5);
  border-radius: 2px;
  transform: translateX(-50%);
}

.control-board {
  height: 50px;
}

.chat-send {
  :deep(.el-input) {
    resize: none;
    border: none;
    outline: none;
  }
}
</style>